package com.cskaoyan.service.wxorder;

import com.cskaoyan.aspect.AnnoFootprint;
import com.cskaoyan.bean.CommonData;
import com.cskaoyan.bean.bo.wxorder.*;
import com.cskaoyan.bean.po.ohter.*;
import com.cskaoyan.bean.po.promotionpo.MarketCoupon;
import com.cskaoyan.bean.po.promotionpo.MarketCouponUser;
import com.cskaoyan.bean.po.wxorder.MarketComment;
import com.cskaoyan.bean.po.wxorder.MarketOrder;
import com.cskaoyan.bean.po.wxorder.MarketOrderExample;
import com.cskaoyan.bean.vo.wxorder.*;
import com.cskaoyan.mapper.*;
import com.cskaoyan.mapper.promotion.MarketCouponMapper;
import com.cskaoyan.mapper.promotion.MarketCouponUserMapper;
import com.cskaoyan.mapper.wxorder.MarketCommentMapper;
import com.cskaoyan.mapper.wxorder.MarketOrderMapper;
import com.cskaoyan.util.common.BeanTransfer;
import com.cskaoyan.util.common.DateUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Zhang Tao
 * @version 1.0.0
 * @description
 * @date since 2022-07-19 14:05
 */
@Service
public class WxOrderServiceImpl implements WxOrderService {
    @Autowired
    MarketOrderMapper marketOrderMapper;
    @Autowired
    MarketOrderGoodsMapper marketOrderGoodsMapper;
    @Autowired
    MarketCommentMapper marketCommentMapper;
    @Autowired
    MarketCartMapper cartMapper;
    @Autowired
    MarketAddressMapper addressMapper;
    @Autowired
    MarketCouponMapper couponMapper;
    @Autowired
    MarketGrouponRulesMapper rulesMapper;
    @Autowired
    MarketGrouponMapper grouponMapper;
    @Autowired
    MarketCouponUserMapper couponUserMapper;
    @Autowired
    MarketSystemMapper systemMapper;

    @Override
    public CommonData<OrderListVo> queryOrderListByUserId(OrderBo orderBo, Integer id) {
        List<OrderListVo> orderListVos = new ArrayList<>();
        PageHelper.startPage(orderBo.getPage(), orderBo.getLimit());
        MarketOrderExample example = new MarketOrderExample();
        MarketOrderExample.Criteria criteria = example.createCriteria();
        Short type = orderBo.getShowType();
        if (type == 0) {
            criteria.andUserIdEqualTo(id).andDeletedEqualTo(false);
        } else {
            criteria.andUserIdEqualTo(id).andDeletedEqualTo(false)
                    .andOrderStatusEqualTo(ShowTypeToOrderState.showType(type));
        }

        List<MarketOrder> marketOrders = marketOrderMapper.selectByExample(example);
        PageInfo<MarketOrder> orderPageInfo = new PageInfo<>(marketOrders);
        for (MarketOrder order : marketOrders) {
            Integer orderId = order.getId();
            MarketOrderGoodsExample example1 = new MarketOrderGoodsExample();
            MarketOrderGoodsExample.Criteria criteria1 = example1.createCriteria();
            criteria1.andOrderIdEqualTo(orderId);
            List<MarketOrderGoods> marketOrderGoods = marketOrderGoodsMapper.selectByExample(example1);

            HandleOption handleOption = HandleInfo.handleOption(order.getOrderStatus());
            String s = order.getOrderStatus().toString();
            String status = OrderStatusText.status(s);
            OrderListVo orderListVo = new OrderListVo(order.getId(),
                    false, order.getOrderSn(),
                    status, order.getActualPrice(),
                    order.getAftersaleStatus(), marketOrderGoods, handleOption);
            orderListVos.add(orderListVo);
        }

        PageInfo<OrderListVo> pageInfo = new PageInfo<>(orderListVos);
        pageInfo.setPages(orderPageInfo.getPages());
        pageInfo.setTotal(orderPageInfo.getTotal());
        return CommonData.data(pageInfo);
    }

    @Transactional
    @Override
    public void insertComment(MarketComment comment) {
        comment.setAddTime(DateUtils.time());
        comment.setUpdateTime(DateUtils.time());
        comment.setDeleted(false);
        marketCommentMapper.insertSelective(comment);
    }

    @Override
    public WxOrderDetail queryOrderDetail(Integer orderId) {
        MarketOrderGoodsExample example = new MarketOrderGoodsExample();
        MarketOrderGoodsExample.Criteria criteria = example.createCriteria();
        criteria.andOrderIdEqualTo(orderId).andDeletedEqualTo(false);
        List<MarketOrderGoods> orderGoods = marketOrderGoodsMapper.selectByExample(example);
        MarketOrder marketOrder = marketOrderMapper.selectByPrimaryKey(orderId);
        HandleOption handleOption = HandleInfo.handleOption(marketOrder.getOrderStatus());
        List<String> expressInfo = new ArrayList<>();
        WxOrderInfo orderInfo = new WxOrderInfo();
        WxOrderInfo transfer = null;
        try {
            transfer = (WxOrderInfo) BeanTransfer.transfer(marketOrder, orderInfo);
            transfer.setHandleOption(handleOption);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return new WxOrderDetail(expressInfo, orderGoods, transfer);
    }

    @Transactional
    @Override
    public void orderRefund(Integer orderId) {
        MarketOrder marketOrder = marketOrderMapper.selectByPrimaryKey(orderId);
        marketOrder.setRefundAmount(marketOrder.getActualPrice());
        marketOrder.setRefundTime(DateUtils.time());
        marketOrder.setAftersaleStatus((short) 1);
        marketOrder.setUpdateTime(DateUtils.time());
        marketOrderMapper.updateByPrimaryKeySelective(marketOrder);
    }

    @Transactional
    @Override
    public void orderDelete(Integer orderId) {
        MarketOrder marketOrder = marketOrderMapper.selectByPrimaryKey(orderId);
        marketOrder.setUpdateTime(DateUtils.time());
        marketOrder.setEndTime(DateUtils.time());
        marketOrder.setDeleted(true);
        marketOrderMapper.updateByPrimaryKeySelective(marketOrder);


    }

    @Transactional
    @Override
    public void orderConfirm(Integer orderId) {
        MarketOrder marketOrder = marketOrderMapper.selectByPrimaryKey(orderId);
        marketOrder.setUpdateTime(DateUtils.time());
        marketOrder.setOrderStatus((short) 401);
        marketOrder.setConfirmTime(DateUtils.time());
        marketOrderMapper.updateByPrimaryKeySelective(marketOrder);

    }

    @Transactional
    @Override
    public void orderCancel(Integer orderId) {
        MarketOrder marketOrder = new MarketOrder();
        marketOrder.setDeleted(true);
        marketOrder.setUpdateTime(DateUtils.time());
        marketOrder.setOrderStatus((short) 102);
        marketOrderMapper.updateByPrimaryKeySelective(marketOrder);

    }

    @Override
    public MarketOrderGoods queryOrderGoods(Integer orderId, Integer goodsId) {
        MarketOrderGoodsExample example = new MarketOrderGoodsExample();
        MarketOrderGoodsExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false).andOrderIdEqualTo(orderId).
                andGoodsIdEqualTo(goodsId);
        List<MarketOrderGoods> marketOrderGoods = marketOrderGoodsMapper.selectByExample(example);
        for (MarketOrderGoods marketOrderGood : marketOrderGoods) {
            if (marketOrderGood != null) {
                return marketOrderGood;
            }
        }
        return null;
    }

    @Transactional

    @Override
    public void prepay(Integer orderId) {
        MarketOrder marketOrder = new MarketOrder();
        marketOrder.setId(orderId);
        marketOrder.setUpdateTime(DateUtils.time());
        marketOrder.setOrderStatus((short) 201);
        marketOrderMapper.updateByPrimaryKeySelective(marketOrder);
    }

    @Transactional
    @Override
    public WxOrderSubmitVo submit(WxOrderSubmit submitBO, Integer userId) {
        List<MarketCart> marketCarts = new ArrayList<>();

        if (submitBO.getCartId() != 0) {
            MarketCart cart = cartMapper.selectByPrimaryKey(submitBO.getCartId());
            marketCarts.add(cart);
        } else {
            List<MarketCartExample> examples = new ArrayList<>();
            for (MarketCartExample example : examples) {
                MarketCartExample.Criteria criteria = example.createCriteria();
                criteria.andDeletedEqualTo(false).andCheckedEqualTo(true).andUserIdEqualTo(userId);
                List<MarketCart> marketCarts1 = cartMapper.selectByExample(example);
                for (MarketCart marketCart : marketCarts1) {
                    marketCarts.add(marketCart);
                }
            }

        }

        //购物车
        MarketCart cart = cartMapper.selectByPrimaryKey(submitBO.getCartId());

        // addressId 查询地址信息
        MarketAddress address = addressMapper.selectByPrimaryKey(submitBO.getAddressId());
        //优惠券
        MarketCoupon coupon = couponMapper.selectByPrimaryKey(submitBO.getCouponId());
        //用户优惠券
        // MarketCouponUser couponUser = couponUserMapper.selectByPrimaryKey(submitBO.getUserCouponId());
        // //团购规则
        // MarketGrouponRules grouponRules = rulesMapper.selectByPrimaryKey(submitBO.getGrouponRulesId());
        // // 团购
        // MarketGroupon groupon = grouponMapper.selectByPrimaryKey(submitBO.getGrouponLinkId());

        MarketOrder marketOrder = new MarketOrder();
        SimpleDateFormat dmDate = new SimpleDateFormat("yyyyMMdd");
        int ran = new Random().nextInt(900000) + 100000;
        marketOrder.setOrderSn(dmDate.format(new Date()).concat(String.valueOf(ran)));
        marketOrder.setOrderStatus((short) 201);
        if (address.getAddressDetail() == null) {
            address.setAddressDetail("");
        }
        marketOrder.setAddress(address.getProvince()
                + address.getCity() +
                address.getAddressDetail());
        marketOrder.setMobile(address.getTel());
        marketOrder.setMessage(submitBO.getMessage());
        marketOrder.setConsignee(address.getName());
        marketOrder.setUserId(userId);
        BigDecimal s = cart.getPrice().multiply(new BigDecimal(String.valueOf(cart.getNumber())));
        marketOrder.setGoodsPrice(s);
//获取运费
        //zhong:运费
        MarketSystemExample systemExample = new MarketSystemExample();
        MarketSystemExample.Criteria systemReg = systemExample.createCriteria();
        systemReg.andKeyNameLike("market_express_freight%");
        systemReg.andDeletedEqualTo(false);
        Map<String, String> expressConf = systemMapper
                .selectByExample(systemExample)
                .stream()
                .collect(Collectors.toMap(MarketSystem::getKeyName, MarketSystem::getKeyValue))
                ;
        BigDecimal minPriceForFreeFreight = new BigDecimal(expressConf.get("market_express_freight_min"));
        BigDecimal freight = new BigDecimal(expressConf.get("market_express_freight_value"));
        if (s.compareTo(minPriceForFreeFreight) > -1) {
            //goodsTotalPrice >= minPriceForFreeFreight,商品总价达到免运费最低价
            freight = BigDecimal.valueOf(0);
        }
        BigDecimal couponPrice = (coupon == null) ? new BigDecimal(0) : coupon.getDiscount();
        marketOrder.setFreightPrice(freight);
        marketOrder.setCouponPrice(couponPrice);
        marketOrder.setOrderPrice(s.subtract(freight));
        marketOrder.setActualPrice(s.subtract(freight).subtract(couponPrice));
        // Session session = SecurityUtils.getSubject().getSession();
        // TODO 价格待修改
        // marketOrder.setGoodsPrice((BigDecimal) session.getAttribute("GoodsPrice"));
        // marketOrder.setFreightPrice((BigDecimal) session.getAttribute("FreightPrice"));
        // marketOrder.setCouponPrice((BigDecimal) session.getAttribute("CouponPrice"));
        // marketOrder.setOrderPrice((BigDecimal) session.getAttribute("OrderPrice"));
        // marketOrder.setActualPrice((BigDecimal) session.getAttribute("ActualPrice"));
        marketOrder.setComments((short) marketCarts.size());
        marketOrder.setIntegralPrice(new BigDecimal(0));
        marketOrder.setAddTime(new Date());
        marketOrder.setGrouponPrice(new BigDecimal(0));
        marketOrder.setPayTime(marketOrder.getPayTime());
        marketOrder.setUpdateTime(new Date());
        marketOrder.setAftersaleStatus((short) 0);
        //     marketOrder.setIntegralPrice(new BigDecimal(0));
        //     marketOrder.setGrouponPrice(new BigDecimal(0));
        //     marketOrder.setComments((short) carts.size());
        //     marketOrder.setAddTime(new Date());
        //     marketOrder.setPayTime(new Date());
        //     marketOrder.setUpdateTime(marketOrder.getPayTime());
        //     marketOrder.setAftersaleStatus((short) 0);
        //
        marketOrderMapper.insertSelective(marketOrder);
        Integer orderId = marketOrder.getId();
        MarketOrderGoods orderGoods = new MarketOrderGoods();
        for (MarketCart cart1 : marketCarts) {
            orderGoods.setGoodsId(cart1.getGoodsId());
            orderGoods.setOrderId(orderId);
            orderGoods.setGoodsName(cart1.getGoodsName());
            orderGoods.setGoodsSn(cart1.getGoodsSn());
            orderGoods.setProductId(cart1.getProductId());
            orderGoods.setNumber(cart1.getNumber());
            orderGoods.setPrice(cart1.getPrice());
            orderGoods.setSpecifications(cart1.getSpecifications());
            orderGoods.setPicUrl(cart1.getPicUrl());
            orderGoods.setComment(0);
            orderGoods.setAddTime(marketOrder.getAddTime());
            orderGoods.setUpdateTime(marketOrder.getUpdateTime());
            marketOrderGoodsMapper.insertSelective(orderGoods);
        }

        //zhong: 下完单清购物车
        cleanCart(submitBO.getCartId());

        return new WxOrderSubmitVo(submitBO.getGrouponLinkId(), orderId);
    }

    @Override
    public List<Integer> getCartIds(Integer userId) {
        MarketCartExample example = new MarketCartExample();
        MarketCartExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId);
        List<Integer> cartIds = cartMapper
                .selectByExample(example)
                .stream()
                .map(MarketCart::getId)
                .collect(Collectors.toList())
                ;
        return cartIds;
    }

    //zhong:下完单要清空购物车
    private void cleanCart(Integer cartId) {
        MarketCart delCart = new MarketCart();
        delCart.setId(cartId);
        delCart.setDeleted(true);
        cartMapper.updateByPrimaryKeySelective(delCart);
    }
}
